/**
 * Copyright (c) 2012, Brent Mucci, Ken Anderson
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **/

#ifndef _MCL_PARAMS_RBSP_HPP
#define _MCL_PARAMS_RBSP_HPP

#include "mcl_bitstream_buffer.hpp"
#include "mcl_bitstream.hpp"
#include "mcl_bitstream_reader.hpp"
#include <vector>

// Structures for Raw Byte Sequence Payloads (RBSP)
// On their own, rbsps are not byte aligned.  
// However, when encapsulated in a NAL unit, the first byte is indeed byte-aligned.
//
// TODO: Currently, the class parameters are in syntactical order based on the specification.
//       In the future, the variables will be re-ordered for better packing efficiency.

namespace mcl 
{
// Page 70
	/*
class RBSPTrailingBits
{
public:
	RBSPTrailingBits(BitstreamBuffer &bitstream);
	unsigned char m_rbsp_stop_one_bit;
	unsigned char m_rbsp_alignment_zero_bit;
};

class RBSPSliceTrailingBits
{
public:
	RBSPSliceTrailingBits(BitstreamBuffer &bitstream);
	unsigned int m_cabac_zero_word;
};

class SliceDataPartitionCLayerRBSP
{
public:
	SliceDataPartitionCLayerRBSP(BitstreamBuffer &bitstream);
	unsigned int m_slice_id;
	unsigned char m_colour_plane_id;
	unsigned int m_redundant_pic_cnt;
};

class SliceDataPartitionALayerRBSP
{
public:
	SliceDataPartitionALayerRBSP(BitstreamBuffer &bitstream);
	unsigned int m_slice_id;
};

class FillerDataRBSP
{
public:
	FillerDataRBSP(BitstreamBuffer &bitstream);
	unsigned char m_ff_byte;
};

class AccessUnitDelimeterRBSP
{
public:
	AccessUnitDelimeterRBSP(BitstreamBuffer &bitstream);
	unsigned char primary_pic_type;
};


class SeiMessage
{
public:
	SeiMessage(BitstreamBuffer &bitstream);
	unsigned char m_ff_byte;
	unsigned char m_last_payload_type_byte;
	unsigned char m_last_payload_size_byte;
};

class SeiRBSP
{
public:
	SeiRBSP(BitstreamBuffer &bitstream);
};

*/
class SequenceParameterSetData
{
public:
	SequenceParameterSetData(Bitstream &bitstream);

	unsigned char m_profile_idc;
	unsigned char m_constraint_set0_flag;
	unsigned char m_constraint_set1_flag;
	unsigned char m_constraint_set2_flag;
	unsigned char m_constraint_set3_flag;
	unsigned char m_constraint_set4_flag;
	unsigned char m_constraint_set5_flag;
	unsigned char m_reserved_zero_2bits;
	unsigned char m_level_idc;
	unsigned int  m_seq_parameter_set_id;
	unsigned int  m_chroma_format_idc;
	unsigned char m_separate_colour_plane_flag;
	unsigned int  m_bit_depth_luma_minus8;
	unsigned int  m_bit_depth_chroma_minus8;
	unsigned char m_qpprime_y_zero_transform_bypass_flag;
	unsigned char m_seq_scaling_matrix_present_flag;
	std::vector<unsigned char> m_seq_scaling_list_present_flag;
	unsigned int  m_log2_max_frame_num_minus4;
	unsigned int  m_pic_order_cnt_type;
	unsigned int  m_log2_max_pic_order_cnt_lsb_minus4;
	unsigned char m_delta_pic_order_always_zero_flag;
	signed int    m_offset_for_non_ref_pic;
	signed int    m_offset_for_top_to_bottom_field;
	unsigned int  m_num_ref_frames_in_pic_order_cnt_cycle;
	std::vector<signed int> m_offset_for_ref_frame;
	unsigned int  m_max_num_ref_frames;
	unsigned char m_gaps_in_frame_num_value_allowed_flag;
	unsigned int  m_pic_width_in_mbs_minus1;
	unsigned int  m_pic_height_in_map_units_minus1;
	unsigned char m_frame_mbs_only_flag;
	unsigned char m_mb_adaptive_frame_field_flag;
	unsigned char m_direct_8x8_inference_flag;
	unsigned char m_frame_cropping_flag;
	unsigned int  m_frame_crop_left_offset;
	unsigned int  m_frame_crop_right_offset;
	unsigned int  m_frame_crop_top_offset;
	unsigned int  m_frame_crop_bottom_offset;
	unsigned char m_vui_parameters_present_flag;
};

class PictureParameterSetRBSP
{
public:
	PictureParameterSetRBSP(Bitstream &bitstream, SequenceParameterSetData &sequenceParameter);

	unsigned int  m_pic_parameter_set_id;
	unsigned int  m_seq_parameter_set_id;
	unsigned char m_entropy_coding_mode_flag;
	unsigned char m_bottom_field_pic_order_in_frame_present_flag;
	unsigned int  m_num_slice_groups_minus1;
	unsigned int  m_slice_group_map_type;
	std::vector<unsigned int> m_run_length_minus1;
	std::vector<unsigned int> m_top_left;
	std::vector<unsigned int> m_bottom_right;
	unsigned char m_slice_group_change_direction_flag;
	unsigned char m_slice_group_change_rate_minus1;
	unsigned char m_pic_size_in_map_units_minus1;
	std::vector<unsigned int> m_slice_group_id;
	unsigned int m_num_ref_idx_l0_default_active_minus1;
	unsigned int m_num_ref_idx_l1_default_active_minus1;
	unsigned char m_weighted_pred_flag;
	unsigned char m_weighted_bipred_idc;
	signed int m_pic_init_qp_minus26;
	signed int m_pic_init_qs_minus26;
	signed int m_chroma_qp_index_offset;
	unsigned char m_deblocking_filter_control_present_flag;
	unsigned char m_constrained_intra_pred_flag;
	unsigned char m_redundant_pic_cnt_present_flag;
	unsigned char m_transform_8x8_mode_flag;
	unsigned char m_pic_scaling_matrix_present_flag;
	std::vector<unsigned char> m_pic_scaling_list_present_flag;
	signed int m_second_chroma_qp_index_offset;
};

class SubsetSequenceParameterSetRBSP
{
public:
	SubsetSequenceParameterSetRBSP(Bitstream &bitstream);

	unsigned char m_svc_vui_parameters_present_flag;
	unsigned char m_bit_equal_to_one;
	unsigned char m_mvc_vui_parameters_present_flag;
	unsigned char m_additional_extension2_flag;
	unsigned char m_additional_extension2_data_flag;
};

class SequenceParameterSetExtensionRBSP
{
public:
	SequenceParameterSetExtensionRBSP(Bitstream &bitstream);

	unsigned int  m_seq_parameter_set_id;
	unsigned int  m_aux_format_idc;
	unsigned int  m_bit_depth_aux_minus8;
	unsigned char m_alpha_incr_flag;
	unsigned int  m_alpha_opaque_value;
	unsigned int  m_alpha_transparent_value;
	unsigned char m_additional_extension_flag;
};

class ScalingList
{
public:
	ScalingList(std::vector<char> scalingList, unsigned int sizeOfScalingList, char &useDefaultScalingMatrixFlag);

	signed int m_delta_scale;
};

class SequenceParameterSetRBSP
{
public:
	SequenceParameterSetRBSP(Bitstream &bitstream);

	SequenceParameterSetData m_sequence_parameter_set_data;
};

};

#endif